import pandas as pd
df = pd.read_excel('旅游网站精华游记数据.xlsx')
def dealPlace(place):					#筛选途经地点中的中文地名
    s = ''
    if type(place) == str:
        for c in place:
            if not (((c >= 'a') and (c <= 'z'))
                    or ((c >= 'A') and (c <= 'Z'))):
                s = s + c
    else:
        s = place
    return s
def dealView(view):						#统一阅览数中的数值格式
    num = view
    if type(num) == str:
        if '万' in num:
            if '.' in num:
                num = num.replace('.', '').replace('万', '000')
            else:
                num = num.replace('万', '0000')
    return num
df['出发日期'] = df['出发日期'].str.split(expand=True)[0]
df['天数'] = df['天数'].str.slice(1, -1).astype('int')
df['人均消费（元）'] = df['人均消费（元）'].str.slice(2, -1)
#使用lambda调用dealPlace()函数
df['途经地点'] = df['途经地点'].apply(lambda x: dealPlace(x))
df['途经地点'] = df['途经地点'].str.replace('途经：', '', regex=False).str.replace('>', '、', regex=False)
#使用lambda调用dealView()函数
df['阅览数'] = df['阅览数'].apply(lambda x: dealView(x)).astype('int')
print(df[['出发日期', '天数', '人均消费（元）', '阅览数', '途经地点']])

'''这段代码是对旅游网站精华游记数据进行完整预处理的流程，核心目标是：清洗数据格式、去除重复 / 缺失 / 异常值、提取关键信息，最终输出标准化的 Excel 文件。以下逐段详细解释：
一、整体流程概览
数据读取 → 2. 字段格式标准化（日期 / 天数 / 消费 / 途经地 / 阅览数）→ 3. 去除重复值 → 4. 处理缺失值 → 5. 剔除异常值 → 6. 提取衍生字段（月份）→ 7. 保存结果
二、逐段代码解释
1. 导入库与读取数据
python
运行
import pandas as pd
df = pd.read_excel('旅游网站精华游记数据.xlsx')
import pandas as pd：导入数据分析库 Pandas，并用别名pd简化调用（行业通用写法）。
df = pd.read_excel(...)：读取 Excel 文件，将数据存储在 Pandas 的DataFrame（表格型数据结构）中，变量名df代表原始数据。
2. 自定义数据清洗函数
定义两个辅助函数，分别处理「途经地点」和「阅览数」的格式问题：
（1）dealPlace(place)：筛选途经地点中的中文（去除字母）
python
运行
def dealPlace(place):  # 筛选途经地点中的中文地名
    s = ''
    if type(place) == str:  # 仅处理字符串类型（避免空值/非字符串报错）
        for c in place:  # 遍历字符串中每个字符
            # 排除英文字母（a-z、A-Z），保留中文、符号等
            if not (((c >= 'a') and (c <= 'z')) or ((c >= 'A') and (c <= 'Z'))):
                s = s + c  # 拼接保留的字符
    else:
        s = place  # 非字符串类型（如NaN）直接返回原值
    return s
作用：原始「途经地点」可能包含字母（如网址、英文标注），此函数仅保留中文和符号，剔除所有英文字母。
示例：输入"途经：Beijing>上海>Guangzhou" → 输出"途经：>上海>"（后续会进一步清理符号）。
（2）dealView(view)：统一阅览数的数值格式（处理「万」单位）
python
运行
def dealView(view):  # 统一阅览数中的数值格式
    num = view
    if type(num) == str:  # 仅处理字符串类型（原始可能是"1.2万"、"5万"等）
        if '万' in num:  # 若包含"万"字（如"1.2万"=12000，"5万"=50000）
            if '.' in num:  # 处理带小数点的情况（如"1.2万"）
                num = num.replace('.', '').replace('万', '000')  # "1.2万"→"12"+"000"→"12000"
            else:  # 处理无小数点的情况（如"5万"）
                num = num.replace('万', '0000')  # "5万"→"5"+"0000"→"50000"
    return num
作用：将带「万」单位的字符串转为纯数字字符串，方便后续转为整数（如 "3.8 万"→"38000"）。
注意：若原始阅览数已是数字（如 1234），则直接返回，不做处理。
3. 核心字段格式清洗
对「出发日期」「天数」「人均消费」「途经地点」「阅览数」5 个关键字段做标准化处理：
（1）处理「出发日期」：提取日期部分（去除多余信息）
python
运行
df['出发日期'] = df['出发日期'].str.split(expand=True)[0]
假设原始「出发日期」格式如"2023-10-01 周一"或"2023/05/15 出发"，str.split()按空格分割字符串，expand=True转为表格，[0]取第一列
（仅保留纯日期字符串，如 "2023-10-01"）。
（2）处理「天数」：提取数字并转为整数
python
运行
df['天数'] = df['天数'].str.slice(1, -1).astype('int')
假设原始「天数」格式如"3天"「"5 日"」，str.slice(1, -1)截取字符串第 1 到倒数第 1 个字符（去掉开头的数字和结尾的单位，如 "3 天"→"3"），
再用astype('int')转为整数类型。
（3）处理「人均消费（元）」：去除前缀字符
python
运行
df['人均消费（元）'] = df['人均消费（元）'].str.slice(2, -1)
假设原始格式如"人均5000元"，str.slice(2, -1)截取第 2 到倒数第 1 个字符（去掉 "人均" 和 "元"，保留数字部分，如 "5000"）。
注：此处未转为数值类型（如int），可能是因为原始数据中存在非数字值（如 "未知"），需后续根据需求调整。
（4）处理「途经地点」：调用函数 + 清理符号
python
运行
# 使用lambda调用dealPlace()函数（对每一行的「途经地点」应用函数）
df['途经地点'] = df['途经地点'].apply(lambda x: dealPlace(x))
# 去除"途经："前缀，将">"转为中文顿号"、"（统一分隔符）

df['途经地点'] = df['途经地点'].str.replace('途经：', '', regex=False).str.replace('>', '、', regex=False)
示例：经dealPlace处理后为"途经：>上海>" → 最终输出"上海、"（若有多个地点则为"上海、杭州、苏州"）。
regex=False：表示按普通字符串匹配（而非正则表达式），避免特殊字符（如:）被误解析。
（5）处理「阅览数」：调用函数 + 转为整数
python
运行
# 使用lambda调用dealView()函数，统一格式后转为整数类型
df['阅览数'] = df['阅览数'].apply(lambda x: dealView(x)).astype('int')
示例：原始"3.8万" → 经dealView转为"38000" → 最终转为整数38000。
输出清洗后的核心字段
python
运行
print(df[['出发日期', '天数', '人均消费（元）', '阅览数', '途经地点']])
打印上述 5 个字段的清洗结果，用于快速验证格式是否符合预期。'''
df1=df.duplicated(subset=['标题'])
print('除包含重复值的第一行外，其它包含重复值标记为True的行：\n',df1[df1==True])
print('删除重复值前数据的行数：',len(df))
df.drop_duplicates(subset=['标题'],inplace=True,ignore_index=True)
print('删除重复值后数据的行数：',len(df))
df2=df.T.isnull().sum()
print('缺失值个数大于2的行：\n',df2[df2>2])
print('删除缺失值前数据的行数：',len(df))
df.dropna(thresh=5,inplace=True)
print('删除缺失值后数据的行数：',len(df))
val=df['天数'][(df['天数']>15)]
print('天数大于15的异常值个数：',val.count())
print('天数大于15的异常值前10行：\n',val.head(10))
print('删除异常值前数据的行数：',len(df))
df.drop(val.index,inplace=True)
print('删除异常值后数据的行数：',len(df))
df['月份']=pd.to_datatime(df['出发日期']).df.month
print(df[['出发日期','月份']].head(20))
df.to_excel('旅游网站精华游记数据.xlsx',index=False)